# language: JSVM2

/**
 * @fileoverview js.lang.StringBuffer class {@link http://jsvm.org/}
 * @file		StringBuffer.jsc
 * @author	Wan Changhua
 * @version	2.01, 10/23/05
 * @since		JSVM2.0
 */

package js.lang;

/**
 * Create a new StringBuffer instance.
 * A string buffer implements a mutable string, it can be modified.
 * Inherit from JObject
 * @author	Wan Changhua
 * @version	2.01, 10/23/05
 * @extends JObject
 * @class this is a StringBuffer class
 * @constructor
 * @final
 * @return A new StringBuffer instance
 * @see JObject js.lang.JObject is the base class for this
 */

class StringBuffer (s) {

	/**
	 * @private
	 */
	var strs = [];
	var str = null;
	var curr = 0;

	/**
	 * Appends the string to this string buffer. 
	 * @param {String} s a string
	 * @return  a reference to this <code>StringBuffer</code>.
	 * @type StringBuffer
	 */
	this.append = function(s) {
		strs[curr++] = String(s);
		str = null;
		return this;
	}

	/**
	 * Inserts the string representation of a subarray of the <code>str</code>
	 * @param {int} index position at which to insert subarray.
	 * @param {String} s a string.
	 * @return  This string buffer.
	 * @type StringBuffer
	 */
	this.insert = function(index, s) {
		var v = this.toString();
		str = v.substring(0, index) 
			+ s + v.substring(index);
		strs = [str];
		curr = 1;
		return this;
	}

	/**
	 * Returns the index within this string of the first occurrence of the
	 * specified substring.
	 * @param {String} s any string.
	 * @return  if the string argument occurs as a substring within this
	 * 	        object, then the index of the first character of the first
	 *          such substring is returned;
	 * @type int
	 */
	this.indexOf = function (s) {
		return this.toString().indexOf(s);
	}
	
	/**
	 * Returns the index within this string of the rightmost occurrence
	 * of the specified substring.
	 * @param {String} s any string.
	 * @return  if the string argument occurs one or more times as a substring
	 *          within this object, then the index of the first character of
	 *          the last such substring is returned. If it does not occur as
	 *          a substring, <code>-1</code> is returned.
	 * @type int
	 */
	this.lastIndexOf = function (s) {
		return this.toString().lastIndexOf(s);
	}
	
	/**
	 * Returns a new String that contains a subsequence of
	 * characters currently contained in this <code>StringBuffer</code>.The 
	 * substring begins at the specified index and extends to the end of the
	 * <code>StringBuffer</code>.
	 * @param  start The beginning index, inclusive.
	 * @return The new string.
	 * @type int
	 */
	this.substring = function (st, ed) {
		return (ed) ? this.toString().substring(st)
			: this.toString().substring(st, ed);
	}

	/**
	 * Converts to a string representing the data in this string buffer.
	 * A new String object is allocated and initialized to 
	 * contain the character sequence currently represented by this 
	 * string buffer. This String is then returned. Subsequent 
	 * changes to the string buffer do not affect the contents of the String.
	 * @return  a string representation of the string buffer.
	 * @type String
	 */
	this.toString = function() {
		if (str == null) {
			str = strs.join("");
			strs = [str];
			curr = 1;
		}
		return str;
	}

	/**
	 * Returns the length (character count) of this string buffer.
	 * @return  the length of the sequence of characters currently 
	 *          represented by this string buffer.
	 * @type int
	 */
	this.length = function() {
		return this.toString().length;
	}

	/**
	 * Sets the length of this String buffer.
	 * @param l the new length of the buffer.
	 * @see #length()
	 */
	this.setLength = function(l) {
		l = (l < 0) ? 0 : l;
		l = (l > this.length()) ? this.length() : l;
		str = str.substring(0, l);
		strs = new Array(str);
		curr = 1;
	}
	
	/**
	 * First thing---append the argument
	 * @ignore
	 */
	if (s != null) {
		this.append(s);
	}

}
